#include "Switch.h"
#include "main.h"
#include "malloc.h"
#include "py32f0xx_hal_gpio.h"
#include "user_led.h"
#include "Model_info.h"
void Send_Switch_Response(uint8_t status);

Switch_Model_t sw_model;
Switch_Retry_t sw_retry;
Switch_Filter_t sw_filter;

//打开输入开关指示灯
void Set_LED_DI(uint8_t status)
{
	if(status==SW_ON)
	{
		HAL_GPIO_WritePin(LED_DI_GPIO_Port, LED_DI_Pin, GPIO_PIN_SET);
	}
	else if(status==SW_OFF)
	{
		HAL_GPIO_WritePin(LED_DI_GPIO_Port, LED_DI_Pin, GPIO_PIN_RESET);
	}
}
/// @brief 反馈状态指示灯
/// @param status 状态
void Set_LED_FB(uint8_t status)
{
	if(status==SW_ON)
	{
		HAL_GPIO_WritePin(LED_FB_GPIO_Port, LED_FB_Pin, GPIO_PIN_SET);
	}
	else if(status==SW_OFF)
	{
		HAL_GPIO_WritePin(LED_FB_GPIO_Port, LED_FB_Pin, GPIO_PIN_RESET);
	}
}
void sw_sync_status(Switch_Protocol sw)
{
	Set_LED_FB(sw.status.relay_out);
}
//接收响应状态
void Recive_Switch_Response(uint8_t status)
{
	Set_LED_FB(status);
	sw_retry.response_step=ResPonse_step_success;
}
/// @brief lora 开关数据接收函数
/// @param data 数据
/// @param len 数据长度
void Lora_Switch_Recive(uint8_t *data,uint8_t len)
{
	Switch_Protocol sw;
	if(len==sizeof(Switch_Protocol))
	{
		mymemcpy((uint8_t *)&sw,data,len);
		if(sw.id==model_info_handle.general_info.SN)
		{
			if(sw.type==SW_Control)
		  {
		  }
		  else if(sw.type==SW_Response)
		  {
				 Recive_Switch_Response(sw.status.relay_out);
		  }
		  else if(sw.type==SW_Heartbeat_Response)
		  {
			  sw_sync_status(sw);
		  }
			Heartbeat_Receive();
	  }
	}
}
/***************************
*初始化响应重发
****************************/
void Init_Reply_Response(Switch_Retry_t *reply)
{
	reply->response_step=ResPonse_step_success;
	reply->time=0;
	reply->retry_number=0;
	reply->wait_time=500;
}
/****************************
 *等待响应
****************************/
void Start_Switch_Response_Wait(Switch_Retry_t *retry)
{
	retry->response_step=Response_step_wait;
	retry->time=0;
}
//获取开关状态响应
uint8_t Get_Switch_Response(Switch_Retry_t *retry,uint8_t time)
{
	uint8_t status=0;
	switch(retry->response_step)
	{
		case ResPonse_step_success:   //响应成功
			status=0;
			break;
		case Response_step_wait:
			retry->time+=time;
		  if(retry->time>retry->wait_time)
			{
				retry->time=0;
				status=1;                //响应超时
			}
			break;
		case ResPonse_step_overtime:   
			retry->time+=time;
		  if(retry->time>retry->wait_time)
			{
				if(retry->retry_number<10)
				{
					retry->time=0;
					status=1;              //响应超时
				}
				else
				{
					status=2;
				}
			}
			break;
	}
	return status;
}
/// @brief 发送开关控制状态
/// @param status 状态
void Send_Switch_Control(uint8_t status)
{
	Switch_Protocol sw;
	sw.id=model_info_handle.general_info.SN;
	sw.status.sw_in=status;
	sw.type=SW_Control;
	User_LoRaSend_Data((uint8_t *)&sw,sizeof(Switch_Protocol));
}
/// @brief 查询开关输入状态
/// @param  
/// @return 开关引脚状态
uint8_t GetSW_Pin_IN(void)
{
	uint8_t sw=HAL_GPIO_ReadPin(SWITCH_IN_GPIO_Port,SWITCH_IN_Pin);
	if(sw==0)
	{
		return SW_OFF;
	}
	else
	{
		return SW_ON;
	}
}
/// @brief 开关状态滤波器
/// @param filter 滤波器
/// @param status 状态
/// @param time 时间
/// @return 滤波后的开关状态
uint8_t SW_Filter_State(Switch_Filter_t *filter,uint8_t status,uint8_t time)
{
	if(status!=filter->in_last_status)
	{
		filter->time=0;
		filter->in_last_status=status;
	}
	else
	{
		filter->time+=time;
		if(filter->time>=filter->filter_time)
	  {
			filter->time=filter->filter_time;
			filter->out_status=status;
	  }
	}
	return filter->out_status;
}
//初始化开关滤波器
uint8_t Init_SW_Filter(Switch_Filter_t *filter,uint16_t filter_time)
{
	filter->filter_time=filter_time;
	filter->out_status=SW_OFF;
	filter->in_last_status=SW_OFF;
	filter->time=0;
}
//用户接口，查询开关输入状态
uint8_t User_Get_Sw_status()
{
	return sw_model.SW_IN_Status;  
}
//用户查询继电器状态
uint8_t User_Get_Relay_status()
{
	return sw_model.SW_OUT_Status;
}
void Switch_Init()
{
	Init_SW_Filter(&sw_filter,200);
	Set_LED_DI(SW_OFF);
	Set_LED_FB(SW_OFF);
	sw_model.SW_IN_Status=SW_OFF;	
	Init_Reply_Response(&sw_retry);   //初始化重发管理
}
/// @brief 开关线程
/// @param paremeter 
void Switch_Loop(uint8_t ms)
{
	uint8_t in_status;
	in_status=SW_Filter_State(&sw_filter,GetSW_Pin_IN(),20);    //开关状态
	if(in_status!=sw_model.SW_IN_Status)                    //状态变化
	{
		Set_LED_DI(in_status);
		Send_Switch_Control(in_status);                     //发送开关状态
		Start_Switch_Response_Wait(&sw_retry);              //等待响应
		sw_model.SW_IN_Status=in_status;
	}
	if(Get_Switch_Response(&sw_retry,ms)==1)
	{
		Send_Switch_Control(in_status);                     //发送开关状态
	}
}
